package com.ds.infra.ibatis.session;

import com.ds.infra.ibatis.binding.MapperRegistry;
import com.ds.infra.ibatis.mapping.MappedStatement;
import com.ds.infra.ibatis.reflection.MetaObject;
import com.ds.infra.ibatis.type.TypeHandlerRegistry;
import lombok.Data;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 作用： 配置类，用于存储数据源、映射语句等信息。
 *
 * @author WeiShaoying
 */
@Data
public class Configuration {

    // 数据源
    private DataSource dataSource;

    // 存储映射语句
    private final Map<String, MappedStatement> mappedStatements = new HashMap<>();

    // 存储映射接口的注册表
    private final MapperRegistry mapperRegistry = new MapperRegistry(this);

    // 存储类型处理器注册表，用于处理Java类型和数据库类型的转换
    private final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();

    public MappedStatement getMappedStatement(String id) {
        MappedStatement ms = mappedStatements.get(id);
        if (ms == null) {
            throw new RuntimeException("Unknown MappedStatement: " + id);
        }
        return ms;
    }

    // 添加映射语句到配置中
    public void addMappedStatement(MappedStatement mappedStatement) {
        if (mappedStatement == null || mappedStatement.getId() == null) {
            throw new RuntimeException("MappedStatement or its id cannot be null");
        }
        mappedStatements.put(mappedStatement.getId(), mappedStatement);
    }

    public <T> void addMapper(Class<T> type) {
        mapperRegistry.addMapper(type);
    }

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
    }

    public MetaObject newMetaObject(Object object) {
        return new MetaObject(object);
    }
}
